Categories
Gatsby.js

Gatsby.js — useStaticQuery and Slugs

Spread the love

Gatsby is a static web site framework that’s based on React.

We can use it to create static websites from external data sources and more.

In this article, we’ll look at how to create a site with Gatsby.

Query with useStaticQuery Hook

We can use the useStaticQuery hook to query for data.

For example, we can write:

gatsby-config.js

module.exports = {
  siteMetadata: {
    title: "My Homepage",
    description: "This is where I write my thoughts.",
  },
}

src/pages/index.js

import React from "react"
import { graphql, useStaticQuery } from 'gatsby'

export default function Home() {
  const data = useStaticQuery(graphql`
    query HeaderQuery {
      site {
        siteMetadata {
          title
        }
      }
    }
  `)

  return (
    <header>
      <h1>{data.site.siteMetadata.title}</h1>
    </header>
  )
}

We have the site’s metadata in gatsby-config.js .

Then we can query for them in the index.js file.

We pass in our GraphQL query into the useStaticQuery hook.

And that returns the data that we need.

Then we render the title in the JSX.

We can create our own hooks with the useStaticQuery hook.

For instance, we can write:

import React from "react"
import { graphql, useStaticQuery } from 'gatsby'

const useSiteMetadata = () => {
  const { site } = useStaticQuery(
    graphql`
      query SiteMetaData {
        site {
          siteMetadata {
            title
            description
          }
        }
      }
    `
  )
  return site.siteMetadata
}

export default function Home() {
  const { title, description } = useSiteMetadata()

  return (
    <header>
      <h1>{title}</h1>
      <h1>{description}</h1>
    </header>
  )
}

We used the useStaticQuery hook in the useSiteMetadata hook.

We return the siteMetadata and we use that to render the title and description properties of the metadata in gatsby-config.js .

GraphQL Fragments

GraphQL fragments are reusable pieces of a query.

To create a fragment, we use the fragment keyword.

For example, we can write:

import React from "react"
import { graphql } from 'gatsby'

export const query = graphql`
  fragment SiteInformation on Site {
    siteMetadata {
      title
      description
    }
  }

  query {
    site {
      ...SiteInformation
    }
  }
`
export default function Home({ data }) {
  return (
    <div>
      <h1>{data.site.siteMetadata.title}</h1>
      <p>{data.site.siteMetadata.siteDescription}</p>
    </div>
  )
}

We add the fragment into our query GraphQL query object.

We use the ... operator to apply the fragment in our query.

Then we render the result by getting the data from the data prop.

Creating Slugs for Pages

We can create slugs for our pages.

For example, we can write:

gatsby-node.js

const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

We check the node’s type.

If it’s 'MarkdownRemark' , then we create the slug with the createFilePath method.

Then we call createNodeField to add the slug field into our query.

Then in GraphiQL, we can query for it by writing:

{
  allMarkdownRemark {
    edges {
      node {
        fields {
          slug
        }
      }
    }
  }
}

Then we should get a result that looks like:

{
  "data": {
    "allMarkdownRemark": {
      "edges": [
        {
          "node": {
            "fields": {
              "slug": "/post/"
            }
          }
        }
      ]
    }
  },
  "extensions": {}
}

returned.

Conclusion

We can use the useStaticQuery hook to query for data in our Gatsby project.

Also, we can create fragments and slugs in our project.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *